#ifndef SERIALIZATION_H
#define SERIALIZATION_H
#include <QByteArray>
#include <QDataStream>
#include <QFile>

namespace   Serialization
{

template<class T>
inline QByteArray to_byte_array(const T &obj)
{
   QByteArray ba; QString err;
   QDataStream stream((& ba), QIODevice::WriteOnly);
   stream << (quint32)(9438);
   try { stream << obj; }
   catch (const std::exception & e) { err = QString("serialization error '%ERR%'").replace("%ERR%", e.what()); }
   catch (...) { err = QString("serialization error '%ERR%'").replace("%ERR%", "unknown error"); }
   if (! err.isEmpty()) { qDebug("to_byte_array() : %s", qPrintable(err)); ba.clear(); }
   return ba;
}

template <class T>
inline bool from_byte_array(T & obj, const QByteArray & data)
{
   bool result = false;
   if (data.isEmpty())
       return false;
   QDataStream stream(data);
   quint32 magic = 0;
   stream >> magic;
   if (magic != 9438)
       return false;
   stream >> obj;
   result = true;
   return result;
}

template <class T>
inline bool to_file(const T & obj, const QString & sFileName)
{
    QByteArray data = to_byte_array(obj);
    QFile file(sFileName);
    if (! file.open(QIODevice::WriteOnly | QIODevice::Truncate))
        return false;
    file.write(data);
    file.close();
    return true;
}

template <class T>
inline bool from_file(T & obj, const QString & sFileName)
{
    QFile file(sFileName);
    if (! file.open(QIODevice::ReadOnly))
        return false;
    QByteArray data = file.readAll(); file.close();
    return from_byte_array(obj, data);
}

}

#endif // SERIALIZATION_H
